"""
任务分析器

负责分析任务的复杂度、优先级、资源需求等，
为协调引擎提供决策支持。
"""

from typing import Dict, List, Any, Optional, Set, Tuple
from datetime import datetime, timedelta
from enum import Enum
import re
from dataclasses import dataclass

from ..agents.base_agent import Task, TaskPriority
from ..agents.agent_roles import AgentRole, AgentLevel
from .coordination_patterns import CoordinationContext


class TaskComplexity(Enum):
    """任务复杂度"""
    SIMPLE = "simple"           # 简单任务
    MODERATE = "moderate"       # 中等复杂度
    COMPLEX = "complex"         # 复杂任务
    CRITICAL = "critical"       # 关键任务


class TaskCategory(Enum):
    """任务类别"""
    RESEARCH = "research"               # 研究分析
    DECISION = "decision"               # 决策制定
    EXECUTION = "execution"             # 执行操作
    MONITORING = "monitoring"           # 监控观察
    COMMUNICATION = "communication"     # 沟通协调
    EMERGENCY = "emergency"             # 紧急处理


class ResourceType(Enum):
    """资源类型"""
    COMPUTATIONAL = "computational"     # 计算资源
    DATA_ACCESS = "data_access"         # 数据访问
    HUMAN_EXPERTISE = "human_expertise" # 人工专业知识
    EXTERNAL_API = "external_api"       # 外部API
    TIME_SENSITIVE = "time_sensitive"   # 时间敏感


@dataclass
class TaskAnalysisResult:
    """任务分析结果"""
    task_id: str
    complexity: TaskComplexity
    category: TaskCategory
    estimated_duration: timedelta
    required_agents: List[AgentRole]
    required_resources: List[ResourceType]
    dependencies: List[str]
    risk_factors: List[str]
    coordination_requirements: Dict[str, Any]
    confidence_score: float
    analysis_timestamp: datetime


class TaskAnalyzer:
    """任务分析器"""
    
    def __init__(self):
        """初始化任务分析器"""
        # 关键词映射
        self.complexity_keywords = {
            TaskComplexity.SIMPLE: [
                "查询", "获取", "显示", "列出", "检查", "状态",
                "简单", "基础", "单一", "直接"
            ],
            TaskComplexity.MODERATE: [
                "分析", "计算", "比较", "评估", "处理", "转换",
                "中等", "一般", "标准", "常规"
            ],
            TaskComplexity.COMPLEX: [
                "优化", "预测", "建模", "策略", "综合", "集成",
                "复杂", "高级", "深度", "全面"
            ],
            TaskComplexity.CRITICAL: [
                "紧急", "关键", "重要", "风险", "危机", "告警",
                "立即", "马上", "urgent", "critical"
            ]
        }
        
        self.category_keywords = {
            TaskCategory.RESEARCH: [
                "研究", "调研", "分析", "报告", "数据", "信息",
                "market", "research", "analysis", "study"
            ],
            TaskCategory.DECISION: [
                "决策", "选择", "判断", "评估", "建议", "推荐",
                "decision", "choose", "recommend", "evaluate"
            ],
            TaskCategory.EXECUTION: [
                "执行", "操作", "交易", "买入", "卖出", "调整",
                "execute", "trade", "buy", "sell", "adjust"
            ],
            TaskCategory.MONITORING: [
                "监控", "观察", "跟踪", "检测", "预警", "巡检",
                "monitor", "watch", "track", "detect", "alert"
            ],
            TaskCategory.COMMUNICATION: [
                "通知", "报告", "沟通", "协调", "会议", "讨论",
                "notify", "report", "communicate", "coordinate"
            ],
            TaskCategory.EMERGENCY: [
                "紧急", "应急", "故障", "异常", "风险", "危机",
                "emergency", "urgent", "crisis", "risk", "fault"
            ]
        }
        
        self.agent_role_mapping = {
            TaskCategory.RESEARCH: [
                AgentRole.RESEARCH_DIRECTOR, AgentRole.MARKET_ANALYST,
                AgentRole.QUANTITATIVE_ANALYST, AgentRole.FUNDAMENTAL_ANALYST
            ],
            TaskCategory.DECISION: [
                AgentRole.CIO, AgentRole.INVESTMENT_COMMITTEE,
                AgentRole.PORTFOLIO_MANAGER, AgentRole.INVESTMENT_DIRECTOR
            ],
            TaskCategory.EXECUTION: [
                AgentRole.TRADING_DIRECTOR, AgentRole.EXECUTION_TRADER,
                AgentRole.ALGORITHMIC_TRADER, AgentRole.OPERATIONS_DIRECTOR
            ],
            TaskCategory.MONITORING: [
                AgentRole.RISK_DIRECTOR, AgentRole.RISK_ANALYST,
                AgentRole.COMPLIANCE_OFFICER, AgentRole.PERFORMANCE_ANALYST
            ],
            TaskCategory.COMMUNICATION: [
                AgentRole.OPERATIONS_DIRECTOR, AgentRole.COMPLIANCE_OFFICER,
                AgentRole.CLIENT_RELATIONS_MANAGER
            ],
            TaskCategory.EMERGENCY: [
                AgentRole.CIO, AgentRole.RISK_DIRECTOR,
                AgentRole.OPERATIONS_DIRECTOR, AgentRole.COMPLIANCE_OFFICER
            ]
        }
        
        # 分析历史
        self.analysis_history: List[TaskAnalysisResult] = []
        
        # 性能指标
        self.metrics = {
            "total_analyses": 0,
            "accuracy_score": 0.0,
            "average_analysis_time": 0.0,
            "category_distribution": {},
            "complexity_distribution": {}
        }
    
    async def analyze_task(self, task: Task) -> CoordinationContext:
        """
        分析任务并生成协调上下文
        
        Args:
            task: 要分析的任务
            
        Returns:
            协调上下文
        """
        start_time = datetime.now()
        
        try:
            # 执行各项分析
            complexity = self._analyze_complexity(task)
            category = self._analyze_category(task)
            duration = self._estimate_duration(task, complexity, category)
            required_agents = self._identify_required_agents(task, category)
            required_resources = self._identify_required_resources(task, category)
            dependencies = self._analyze_dependencies(task)
            risk_factors = self._identify_risk_factors(task)
            coordination_reqs = self._analyze_coordination_requirements(
                task, complexity, category
            )
            
            # 计算置信度
            confidence = self._calculate_confidence(task, complexity, category)
            
            # 创建分析结果
            analysis_result = TaskAnalysisResult(
                task_id=task.id,
                complexity=complexity,
                category=category,
                estimated_duration=duration,
                required_agents=required_agents,
                required_resources=required_resources,
                dependencies=dependencies,
                risk_factors=risk_factors,
                coordination_requirements=coordination_reqs,
                confidence_score=confidence,
                analysis_timestamp=datetime.now()
            )
            
            # 保存分析历史
            self.analysis_history.append(analysis_result)
            
            # 创建协调上下文
            context = CoordinationContext(
                task_id=task.id,
                task_type=category.value,
                complexity=complexity.value,
                priority=task.priority.value,
                required_agents=required_agents,
                estimated_duration=duration.total_seconds(),
                dependencies=dependencies,
                constraints=coordination_reqs.get("constraints", {}),
                metadata={
                    "analysis_result": analysis_result,
                    "confidence_score": confidence,
                    "risk_factors": risk_factors
                }
            )
            
            # 更新指标
            self._update_metrics(analysis_result, start_time)
            
            return context
            
        except Exception as e:
            # 返回默认上下文
            return CoordinationContext(
                task_id=task.id,
                task_type="general",
                complexity="moderate",
                priority=task.priority.value,
                required_agents=[],
                estimated_duration=3600.0,  # 1小时
                dependencies=[],
                constraints={},
                metadata={"error": str(e)}
            )
    
    def _analyze_complexity(self, task: Task) -> TaskComplexity:
        """分析任务复杂度"""
        text = f"{task.name} {task.description}".lower()
        
        # 关键词匹配得分
        scores = {}
        for complexity, keywords in self.complexity_keywords.items():
            score = sum(1 for keyword in keywords if keyword in text)
            scores[complexity] = score
        
        # 额外的复杂度指标
        if task.priority == TaskPriority.CRITICAL:
            scores[TaskComplexity.CRITICAL] += 2
        
        if len(task.data.get("dependencies", [])) > 3:
            scores[TaskComplexity.COMPLEX] += 1
        
        if "deadline" in task.data and task.data["deadline"]:
            deadline = task.data["deadline"]
            if isinstance(deadline, str):
                # 简单的时间解析
                if "urgent" in deadline.lower() or "asap" in deadline.lower():
                    scores[TaskComplexity.CRITICAL] += 1
        
        # 返回得分最高的复杂度
        if not scores or max(scores.values()) == 0:
            return TaskComplexity.MODERATE
        
        return max(scores, key=scores.get)
    
    def _analyze_category(self, task: Task) -> TaskCategory:
        """分析任务类别"""
        text = f"{task.name} {task.description}".lower()
        
        # 关键词匹配得分
        scores = {}
        for category, keywords in self.category_keywords.items():
            score = sum(1 for keyword in keywords if keyword in text)
            scores[category] = score
        
        # 基于任务数据的额外判断
        task_type = task.data.get("type", "").lower()
        if task_type:
            for category in TaskCategory:
                if task_type in category.value:
                    scores[category] = scores.get(category, 0) + 2
        
        # 返回得分最高的类别
        if not scores or max(scores.values()) == 0:
            return TaskCategory.RESEARCH  # 默认为研究类别
        
        return max(scores, key=scores.get)
    
    def _estimate_duration(
        self,
        task: Task,
        complexity: TaskComplexity,
        category: TaskCategory
    ) -> timedelta:
        """估算任务持续时间"""
        # 基础时间（分钟）
        base_times = {
            TaskComplexity.SIMPLE: 15,
            TaskComplexity.MODERATE: 60,
            TaskComplexity.COMPLEX: 240,
            TaskComplexity.CRITICAL: 30  # 紧急任务通常需要快速处理
        }
        
        # 类别调整因子
        category_factors = {
            TaskCategory.RESEARCH: 1.5,
            TaskCategory.DECISION: 1.2,
            TaskCategory.EXECUTION: 0.8,
            TaskCategory.MONITORING: 0.5,
            TaskCategory.COMMUNICATION: 0.6,
            TaskCategory.EMERGENCY: 0.3
        }
        
        base_time = base_times.get(complexity, 60)
        factor = category_factors.get(category, 1.0)
        
        # 考虑依赖关系
        dependencies = task.data.get("dependencies", [])
        if dependencies:
            factor *= (1 + len(dependencies) * 0.1)
        
        # 考虑优先级
        if task.priority == TaskPriority.CRITICAL:
            factor *= 0.7  # 紧急任务需要快速完成
        elif task.priority == TaskPriority.LOW:
            factor *= 1.3  # 低优先级任务可以慢一些
        
        estimated_minutes = int(base_time * factor)
        return timedelta(minutes=estimated_minutes)
    
    def _identify_required_agents(
        self,
        task: Task,
        category: TaskCategory
    ) -> List[AgentRole]:
        """识别所需的智能体角色"""
        required_agents = self.agent_role_mapping.get(category, [])
        
        # 基于任务内容的额外判断
        text = f"{task.name} {task.description}".lower()
        
        # 特定关键词映射到特定角色
        keyword_role_mapping = {
            "风险": [AgentRole.RISK_DIRECTOR, AgentRole.RISK_ANALYST],
            "合规": [AgentRole.COMPLIANCE_OFFICER],
            "交易": [AgentRole.TRADING_DIRECTOR, AgentRole.EXECUTION_TRADER],
            "量化": [AgentRole.QUANTITATIVE_ANALYST],
            "基本面": [AgentRole.FUNDAMENTAL_ANALYST],
            "技术": [AgentRole.TECHNICAL_ANALYST],
            "宏观": [AgentRole.MACRO_ANALYST],
            "信用": [AgentRole.CREDIT_ANALYST],
            "客户": [AgentRole.CLIENT_RELATIONS_MANAGER],
            "绩效": [AgentRole.PERFORMANCE_ANALYST]
        }
        
        for keyword, roles in keyword_role_mapping.items():
            if keyword in text:
                required_agents.extend(roles)
        
        # 去重并返回
        return list(set(required_agents))
    
    def _identify_required_resources(
        self,
        task: Task,
        category: TaskCategory
    ) -> List[ResourceType]:
        """识别所需资源"""
        text = f"{task.name} {task.description}".lower()
        resources = []
        
        # 基于类别的默认资源
        category_resources = {
            TaskCategory.RESEARCH: [ResourceType.DATA_ACCESS, ResourceType.COMPUTATIONAL],
            TaskCategory.DECISION: [ResourceType.HUMAN_EXPERTISE, ResourceType.DATA_ACCESS],
            TaskCategory.EXECUTION: [ResourceType.EXTERNAL_API, ResourceType.TIME_SENSITIVE],
            TaskCategory.MONITORING: [ResourceType.DATA_ACCESS, ResourceType.COMPUTATIONAL],
            TaskCategory.COMMUNICATION: [ResourceType.HUMAN_EXPERTISE],
            TaskCategory.EMERGENCY: [ResourceType.TIME_SENSITIVE, ResourceType.HUMAN_EXPERTISE]
        }
        
        resources.extend(category_resources.get(category, []))
        
        # 基于关键词的资源识别
        if any(keyword in text for keyword in ["实时", "即时", "紧急", "立即"]):
            resources.append(ResourceType.TIME_SENSITIVE)
        
        if any(keyword in text for keyword in ["计算", "模型", "算法", "分析"]):
            resources.append(ResourceType.COMPUTATIONAL)
        
        if any(keyword in text for keyword in ["数据", "信息", "查询", "获取"]):
            resources.append(ResourceType.DATA_ACCESS)
        
        if any(keyword in text for keyword in ["API", "接口", "外部", "第三方"]):
            resources.append(ResourceType.EXTERNAL_API)
        
        if any(keyword in text for keyword in ["专家", "人工", "审核", "判断"]):
            resources.append(ResourceType.HUMAN_EXPERTISE)
        
        return list(set(resources))
    
    def _analyze_dependencies(self, task: Task) -> List[str]:
        """分析任务依赖"""
        dependencies = task.data.get("dependencies", [])
        
        # 从任务描述中提取可能的依赖
        text = task.description.lower()
        dependency_patterns = [
            r"依赖于\s*(\w+)",
            r"需要\s*(\w+)\s*完成",
            r"等待\s*(\w+)",
            r"基于\s*(\w+)\s*结果"
        ]
        
        for pattern in dependency_patterns:
            matches = re.findall(pattern, text)
            dependencies.extend(matches)
        
        return list(set(dependencies))
    
    def _identify_risk_factors(self, task: Task) -> List[str]:
        """识别风险因素"""
        text = f"{task.name} {task.description}".lower()
        risk_factors = []
        
        # 风险关键词
        risk_keywords = {
            "时间风险": ["紧急", "deadline", "截止", "时限"],
            "数据风险": ["数据缺失", "数据质量", "数据延迟"],
            "技术风险": ["系统故障", "网络问题", "API失效"],
            "市场风险": ["市场波动", "价格变化", "流动性"],
            "操作风险": ["人为错误", "流程问题", "合规风险"],
            "外部风险": ["第三方", "外部依赖", "供应商"]
        }
        
        for risk_type, keywords in risk_keywords.items():
            if any(keyword in text for keyword in keywords):
                risk_factors.append(risk_type)
        
        # 基于任务优先级的风险
        if task.priority == TaskPriority.CRITICAL:
            risk_factors.append("高优先级风险")
        
        # 基于依赖关系的风险
        dependencies = task.data.get("dependencies", [])
        if len(dependencies) > 2:
            risk_factors.append("依赖复杂性风险")
        
        return risk_factors
    
    def _analyze_coordination_requirements(
        self,
        task: Task,
        complexity: TaskComplexity,
        category: TaskCategory
    ) -> Dict[str, Any]:
        """分析协调需求"""
        requirements = {
            "coordination_level": "standard",
            "escalation_threshold": 2,
            "communication_frequency": "normal",
            "approval_required": False,
            "constraints": {}
        }
        
        # 基于复杂度调整
        if complexity == TaskComplexity.CRITICAL:
            requirements["coordination_level"] = "high"
            requirements["escalation_threshold"] = 1
            requirements["communication_frequency"] = "high"
            requirements["approval_required"] = True
        elif complexity == TaskComplexity.COMPLEX:
            requirements["coordination_level"] = "medium"
            requirements["escalation_threshold"] = 2
            requirements["communication_frequency"] = "medium"
        
        # 基于类别调整
        if category == TaskCategory.DECISION:
            requirements["approval_required"] = True
            requirements["coordination_level"] = "high"
        elif category == TaskCategory.EMERGENCY:
            requirements["escalation_threshold"] = 0
            requirements["communication_frequency"] = "immediate"
        
        # 时间约束
        if task.priority == TaskPriority.CRITICAL:
            requirements["constraints"]["max_response_time"] = 300  # 5分钟
        else:
            requirements["constraints"]["max_response_time"] = 1800  # 30分钟
        
        return requirements
    
    def _calculate_confidence(
        self,
        task: Task,
        complexity: TaskComplexity,
        category: TaskCategory
    ) -> float:
        """计算分析置信度"""
        confidence = 0.5  # 基础置信度
        
        # 基于任务描述的详细程度
        description_length = len(task.description)
        if description_length > 100:
            confidence += 0.2
        elif description_length > 50:
            confidence += 0.1
        
        # 基于任务数据的完整性
        task_data_keys = len(task.data.keys())
        confidence += min(task_data_keys * 0.05, 0.2)
        
        # 基于关键词匹配度
        text = f"{task.name} {task.description}".lower()
        complexity_matches = sum(
            1 for keyword in self.complexity_keywords.get(complexity, [])
            if keyword in text
        )
        category_matches = sum(
            1 for keyword in self.category_keywords.get(category, [])
            if keyword in text
        )
        
        if complexity_matches > 0:
            confidence += 0.1
        if category_matches > 0:
            confidence += 0.1
        
        return min(confidence, 1.0)
    
    def _update_metrics(self, result: TaskAnalysisResult, start_time: datetime):
        """更新分析指标"""
        self.metrics["total_analyses"] += 1
        
        # 更新分析时间
        analysis_time = (datetime.now() - start_time).total_seconds()
        total = self.metrics["total_analyses"]
        current_avg = self.metrics["average_analysis_time"]
        self.metrics["average_analysis_time"] = (
            (current_avg * (total - 1) + analysis_time) / total
        )
        
        # 更新分布统计
        category = result.category.value
        if category not in self.metrics["category_distribution"]:
            self.metrics["category_distribution"][category] = 0
        self.metrics["category_distribution"][category] += 1
        
        complexity = result.complexity.value
        if complexity not in self.metrics["complexity_distribution"]:
            self.metrics["complexity_distribution"][complexity] = 0
        self.metrics["complexity_distribution"][complexity] += 1
    
    def get_analysis_history(
        self,
        task_id: Optional[str] = None,
        limit: Optional[int] = None
    ) -> List[TaskAnalysisResult]:
        """获取分析历史"""
        history = self.analysis_history
        
        if task_id:
            history = [r for r in history if r.task_id == task_id]
        
        if limit:
            history = history[-limit:]
        
        return history
    
    def get_metrics(self) -> Dict[str, Any]:
        """获取分析指标"""
        return self.metrics.copy()